import * as vscode from 'vscode';
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import { ChatMessage } from '../../core';
import { LoginService } from './loginService';
import { AnalyticsEvent } from './analyticsService';

// 请求配置接口
interface ProxyConfig {
  baseURL: string;
  timeout: number;
  retryCount: number;
}

// API响应接口
interface ApiResponse<T = any> {
  success: boolean;
  data?: T;
  message?: string;
  code?: number;
  headers?: any;
}

// 用户信息接口
interface UserInfo {
  cnName: string;
  userId: string;
  email?: string;
}

// 反馈参数接口
interface FeedbackParams {
  reportId: string;
  defectId: string;
  status: number;
  reason?: string;
}

// 分页参数接口
interface PaginationParams {
  pageNum: number;
  pageSize: number;
}

// 报告详情参数接口
interface ReportParams {
  reportId: string;
}



// 流式聊天请求参数接口
interface StreamChatParams {
  model: string;
  messages: ChatMessage[];
  stream: boolean;
  temperature?: number;
  max_tokens?: number;
  top_p?: number;
}

export interface ChatDelta {
  content?: string | null;
  tool_calls?: any[];
  role?: 'assistant';
}

/**
 * 代理服务类 - 统一访问后端资源的入口
 * 负责处理所有HTTP请求、身份验证、错误处理等
 */
export class ProxyService {
  private static instance: ProxyService;
  private axiosInstance: AxiosInstance;
  private config: ProxyConfig;
  private context: vscode.ExtensionContext;
  private readonly _onAuthError = new vscode.EventEmitter<string>();
  public readonly onAuthError = this._onAuthError.event;

  private constructor(context: vscode.ExtensionContext) {
    // 初始化配置
    this.config = {
      baseURL: this.getServerUrl(),
      timeout: 90000,
      retryCount: 3
    };

    // 创建axios实例
    this.axiosInstance = this.createAxiosInstance();
    this.context = context;
  }

  /**
   * 获取单例实例
   */
  public static getInstance(context: vscode.ExtensionContext): ProxyService {
    if (!ProxyService.instance) {
      ProxyService.instance = new ProxyService(context  );
    }
    return ProxyService.instance;
  }

  /**
   * 获取服务器URL
   */
  private getServerUrl(): string {
    const urls = {
      DEV: process.env.DEV_URL!,
      BETA: process.env.BETA_URL!,
      TEST: process.env.TEST_URL!,
      PROD: process.env.PROD_URL!
    };

    const env = (process.env.enviroment || 'DEV').toUpperCase();
    return urls[env as keyof typeof urls] || urls.DEV;
  }

  /**
   * 创建axios实例
   */
  private createAxiosInstance(): AxiosInstance {
    const instance = axios.create({
      baseURL: this.config.baseURL,
      timeout: this.config.timeout,
    });

    // 请求拦截器 - 预留用于其他请求处理
    instance.interceptors.request.use(
      (config) => {
        return config;
      },
      (error) => {
        return Promise.reject(error);
      }
    );

    // 响应拦截器 - 统一错误处理
    instance.interceptors.response.use(
      (response) => {
        return response;
      },
      async (error) => {
        const { response } = error;
        
        if (response?.status === 401 && error.config.url !== '/api/user/getUser') {
          // 认证失败，清理登录状态
          await this.handleAuthError('Authentication failed');
          return Promise.reject(new Error('Authentication required'));
        }
        
        if (response?.status >= 500 && error.config.url !== '/api/operation/analytics') {
          vscode.window.showErrorMessage(`服务器错误: ${response.status}`);
        }
        
        return Promise.reject(error);
      }
    );

    return instance;
  }

  /**
   * 获取Cookie
   */
  private async getCookie(): Promise<string | null> {
    try {
      if (!this.context) {
        console.warn('ExtensionContext not available for secureStorage');
        return null;
      }
      const cookie = await this.context.secrets.get('harmonypilot.cookie');
      return cookie || null;
    } catch (error) {
      console.error('读取Cookie失败:', error);
      return null;
    }
  }

  /**
   * 处理认证错误
   */
  private async handleAuthError(message: string): Promise<void> {
    // 清理secureStorage中的cookie
    if (this.context) {
      try {
        await this.context.secrets.delete('harmonypilot.cookie');
      } catch (error) {
        console.error('清理Cookie失败:', error);
      }
    }
    
    // 触发认证错误事件
    this._onAuthError.fire(message);
    
    // 显示带登录按钮的错误消息
    const selection = await vscode.window.showErrorMessage(
      '登录已过期，请重新登录',
      '登录'
    );
    
    // 如果用户点击了登录按钮
    if (selection === '登录') {
      try {
        const loginService = LoginService.getInstance(this.context);
        await loginService.startLogin({
          onSuccess: (userInfo) => {
            vscode.window.showInformationMessage(`登录成功，欢迎 ${userInfo.cnName}！`);
          },
          onFailure: (reason, errorMessage) => {
            vscode.window.showErrorMessage(`登录失败: ${errorMessage}`);
          }
        });
      } catch (error) {
        console.error('启动登录失败:', error);
        vscode.window.showErrorMessage('启动登录失败，请稍后重试');
      }
    }
  }

  /**
   * Sends a single analytics event to the backend.
   * This method handles the actual HTTP request in a "fire-and-forget" manner.
   * @param eventData The event data to send.
   */
  public async sendAnalyticsEvent(eventData: AnalyticsEvent): Promise<void> {
    const analyticsEndpoint = '/api/operation/analytics';
    try {
        // Use the existing post method which has interceptors and error handling.
        // We don't await the result here to avoid blocking the caller.
        this.post(analyticsEndpoint, eventData);
    } catch (error) {
        // The error is already handled by the interceptor and the post method.
        // We can add extra logging here if needed, but for "fire-and-forget" it's optional.
        console.error(`ProxyService: Failed to dispatch analytics event "${eventData.eventName}"`, error);
    }
  }

  /**
   * 通用请求方法
   */
  private async request<T = any>(config: AxiosRequestConfig): Promise<ApiResponse<T>> {
    try {
      // 每次请求前重新加载cookie
      const cookie = await this.getCookie();
      if (cookie) {
        config.headers = {
          ...config.headers,
          cookie: cookie
        };
      }
      
      const response: AxiosResponse = await this.axiosInstance.request(config);
      
      return {
        success: true,
        data: response.data?.data || response.data,
        message: response.data?.message,
        code: response.status,
        headers: response.headers
      };
    } catch (error: any) {
      console.error('API请求失败:', error);
      
      return {
        success: false,
        message: error.message || '请求失败',
        code: error.response?.status || 0,
        headers: error.response?.headers
      };
    }
  }

  /**
   * GET请求
   */
  public async get<T = any>(url: string, params?: any): Promise<ApiResponse<T>> {
    return this.request<T>({
      method: 'GET',
      url,
      params
    });
  }

  /**
   * POST请求
   */
  public async post<T = any>(url: string, data?: any): Promise<ApiResponse<T>> {
    return this.request<T>({
      method: 'POST',
      url,
      data
    });
  }

  /**
   * PUT请求
   */
  public async put<T = any>(url: string, data?: any): Promise<ApiResponse<T>> {
    return this.request<T>({
      method: 'PUT',
      url,
      data
    });
  }

  /**
   * DELETE请求
   */
  public async delete<T = any>(url: string): Promise<ApiResponse<T>> {
    return this.request<T>({
      method: 'DELETE',
      url
    });
  }

  // ==================== 业务API方法 ====================

  /**
   * 获取用户信息
   */
  public async getUserInfo(): Promise<ApiResponse<UserInfo>> {
    return this.post<UserInfo>('/api/user/getUser');
  }

  /**
   * 设置反馈
   */
  public async setFeedback(params: FeedbackParams): Promise<ApiResponse<void>> {
    return this.post('/api/aiService/feedback/set', params);
  }

  /**
   * 获取反馈状态
   */
  public async getFeedbackStatus(defectId: string): Promise<ApiResponse<any>> {
    return this.get(`/api/aiService/feedback/get?defectId=${defectId}`);
  }

  /**
   * 获取所有报告
   */
  public async getAllReports(params: PaginationParams): Promise<ApiResponse<any>> {
    return this.get('/api/aiService/report/getAll', params);
  }

  /**
   * 获取报告详情
   */
  public async getReportDetail(reportId: string): Promise<ApiResponse<any>> {
    return this.get(`/api/aiService/report/detail?reportId=${reportId}`);
  }

  /**
   * 取消报告
   */
  public async cancelReport(reportId: string): Promise<ApiResponse<any>> {
    return this.get(`/api/aiService/report/cancelReport?reportId=${reportId}`);
  }

  /**
   * 获取登录URL
   */
  public async getLoginUrl(): Promise<ApiResponse<{ loginUrl: string }>> {
    return this.get('/api/login');
  }

  /**
   * 验证登录状态
   */
  public async validateLogin(): Promise<boolean> {
    const result = await this.getUserInfo();
    return result.success && !!result.data;
  }

  /**
   * 检查认证状态
   */
  public async checkAuthStatus(): Promise<{
    isAuthenticated: boolean;
    userInfo?: UserInfo;
  }> {
    const result = await this.getUserInfo();
    
    return {
      isAuthenticated: result.success,
      userInfo: result.data
    };
  }

  /**
   * 流式聊天 (兼容BaseLLM接口)
   * 与 baseLLM.ts 中的 _streamChat 方法具有相同签名
   */
  public async *_streamChat(
    _messages: ChatMessage[],
    signal: AbortSignal,
  ): AsyncGenerator<ChatMessage> {
    try {
      // 构建流式聊天参数
      const params: StreamChatParams = {
        model: 'DEFAULT',
        messages: _messages,
        stream: true,
      };

      // 准备请求头
      const headers: any = {};
      const cookie = await this.getCookie();
      if (cookie) {
        headers.cookie = cookie;
      }

      // 发起流式请求
      const response = await this.axiosInstance.request({
        method: 'POST',
        url: '/api/chat/v1/chat/completions',
        data: params,
        headers,
        responseType: 'stream',
        signal // 传递 AbortSignal
      });

      const stream = response.data as NodeJS.ReadableStream;
      let buffer = "";
      let currentMessage: ChatMessage = { role: 'assistant', content: '' };
      
      for await (const chunk of stream) {
          // 检查是否被取消
          if (signal.aborted) {
            throw new Error('Request aborted');
          }
          
          buffer += chunk.toString();
          // SSE acks are separated by newlines
          const lines = buffer.split("\n");
          buffer = lines.pop() || ""; // Retain incomplete line
          
          for (const line of lines) {
              if (line.startsWith("data:")) {
                  const data = line.substring("data:".length).trim();
                  if (data === "[DONE]") {
                      return;
                  }

                  try {
                      const json = JSON.parse(data);
                      const delta = json.choices?.[0]?.delta;
                      if (delta) {
                          if (delta.content) {
                              currentMessage.content = delta.content;
                              // 产出当前完整消息的副本
                              yield { ...currentMessage };
                          }
                      }
                  } catch (e) {
                      console.error("Error parsing SSE data: ", e);
                  }
              }
          }
      }
      
    } catch (error: any) {
      console.error('流式聊天请求失败:', error);
      if (error.name === 'AbortError' || signal.aborted) {
        throw new Error('Request aborted');
      }
      throw error;
    }
  }

  /**
   * 流式聊天 (原有实现)
   */
  public async *streamChat(params: StreamChatParams, signal?: AbortSignal): AsyncGenerator<ChatDelta> {
    try {
      // 准备请求头
      const headers: any = {};
      const cookie = await this.getCookie();
      if (cookie) {
        headers.cookie = cookie;
      }

      // 发起流式请求
      const response = await this.axiosInstance.request({
        method: 'POST',
        url: '/api/chat/v1/chat/completions',
        data: params,
        headers,
        responseType: 'stream',
        signal // 传递 AbortSignal
      });

      const stream = response.data as NodeJS.ReadableStream;
      let buffer = "";
      for await (const chunk of stream) {
          // 检查是否被取消
          if (signal?.aborted) {
            throw new Error('Request aborted');
          }
          
          buffer += chunk.toString();
          // SSE acks are separated by newlines
          const lines = buffer.split("\n");
          buffer = lines.pop() || ""; // Retain incomplete line
          for (const line of lines) {
              if (line.startsWith("data:")) {
                  const data = line.substring("data:".length).trim();
                  if (data === "[DONE]") {
                      return;
                  }

                  try {
                      const json = JSON.parse(data);
                      const delta = json.choices?.[0]?.delta;
                      if (delta) {
                          yield delta;
                      }
                  } catch (e) {
                      console.error("Error parsing SSE data: ", e);
                  }
              }
          }
      }
      
    } catch (error: any) {
      console.error('流式聊天请求失败:', error);
      if (error.name === 'AbortError' || signal?.aborted) {
        throw new Error('Request aborted');
      }
      throw error;
    }
  }

  /**
   * 更新服务器配置
   */
  public updateConfig(newConfig: Partial<ProxyConfig>): void {
    this.config = { ...this.config, ...newConfig };
    
    // 重新创建axios实例
    this.axiosInstance = this.createAxiosInstance();
  }

  /**
   * 获取当前配置
   */
  public getConfig(): ProxyConfig {
    return { ...this.config };
  }

  /**
   * 清理资源
   */
  public dispose(): void {
    this._onAuthError.dispose();
  }
}

// 导出接口供其他模块使用
export type { ChatMessage, StreamChatParams };
